# Copyright (c) 2008, RPI-ACM, Jesse Kempf <jessekempf@gmail.com>
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
# - Redistributions of source code must retain the above copyright notice,
#     this list of conditions and the following disclaimer.
# - Redistributions in binary form must reproduce the above copyright
#     notice, this list of conditions and the following disclaimer in the
#     documentation and/or other materials provided with the distribution.
# - Neither the names of RPI-ACM nor the names of its contributors
#     may be used to endorse or promote products derived from this software
#     without specific prior written permission.
#
#  THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
#  "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
#  TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
#  PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER
#  OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
#  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
#  PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
#  PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
#  LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
#  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
#  SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

"""
A PyNIX module to provide a super-thin Python Standard Logging wrapper around
Unix syslog.
"""

import logging
from syslog import LOG_CRIT, LOG_ERR, LOG_WARNING, LOG_INFO, LOG_DEBUG, \
					LOG_USER, openlog, closelog, syslog

# pylint: disable-msg=W0702
# PSL specifies that *all* exceptions are to be passed up to
# handleError.

class SyslogHandler(logging.Handler):
	"""A handler class which acts as a thin wrapper around Unix-style syslog."""

	primap = {
		"CRITICAL": LOG_CRIT,
		"FATAL": LOG_CRIT,
		"ERROR": LOG_ERR,
		"WARN": LOG_WARNING,
		"WARNING": LOG_WARNING,
		"INFO": LOG_INFO,
		"DEBUG": LOG_DEBUG
	}

	def __init__(self, ident='syslog', logopt=0, facility=LOG_USER):
		"""Initialize the handler. The arguments are passed directly to
		syslog.openlog() for processing."""

		logging.Handler.__init__(self)

		openlog(ident, logopt, facility)

	def close(self):
		"""Closes the log handler."""
		closelog()

	def emit(self, record):
		"""Formats a record and logs it to syslog.
		
			If the priority of the message is unknown, an error will be logged
			and the unknown-priority message logged at LOG_WARNING priority."""
		try:
			pri = SyslogHandler.primap[record.levelname]
		except KeyError:
			pri = LOG_WARNING
			try:
				syslog(LOG_ERR,
					"SyslogHandler: Unknown levelname '%s'" % record.levelname)
			except:
				self.handleError(record)

		try:
			syslog(pri, self.format(record))
		except:
			self.handleError(record)
